package com.nlscan.qdkit.ui.publico.util;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.media.ExifInterface;
import android.media.ThumbnailUtils;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore.Images;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.webkit.MimeTypeMap;
import android.widget.EditText;
import android.widget.ImageView;

import androidx.annotation.ColorInt;

import com.nlscan.qdkit.ui.publico.config.PublicoVariate;
import com.nlscan.qdkit.common.core.app.App;
import com.quvii.qvlib.util.QvSystemUtil;
import com.quvii.qvlib.util.QvTimeUtils;

import java.io.DataOutputStream;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * todo 更名
 */
public class Utils {

    /*获得网络状态 begin*/

    /**
     * 判断是否有网络连接
     */
    public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm == null) {
            return false;
        } else {
            NetworkInfo info = cm.getActiveNetworkInfo();
            return info != null && info.isAvailable();
        }
    }

    /**
     * 判断当前是否是移动网络
     */
    public static boolean isMobileAvailable(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm == null) {
            return false;
        } else {
            NetworkInfo info = cm.getActiveNetworkInfo();
            return info != null
                    && (info.getType() == ConnectivityManager.TYPE_MOBILE);
        }
    }

    /**
     * 判断当前是否是WIFI网络
     */
    public static boolean isWifiAvailable(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm == null) {
            return false;
        } else {
            NetworkInfo info = cm.getActiveNetworkInfo();
            return info != null
                    && info.getType() == ConnectivityManager.TYPE_WIFI;
        }
    }
    /*end*/

    /**
     * 应用程序运行命令获取 Root权限，设备必须已破解(获得ROOT权限)
     *
     * @return 应用程序是/否获取Root权限
     */
    public static boolean upgradeRootPermission(String pkgCodePath) {
        Process process = null;
        DataOutputStream os = null;
        try {
            String cmd = "chmod 777 " + pkgCodePath;
            // 切换到root帐号，会请求root权限
            process = Runtime.getRuntime().exec("su");
            os = new DataOutputStream(process.getOutputStream());
            os.writeBytes(cmd + "\n");
            os.writeBytes("mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system"
                    + "\n");
            os.writeBytes("cat /sdcard/NFCManger.apk > /system/app/NFCManger.apk"
                    + "\n");
            os.writeBytes("mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system"
                    + "\n");
            os.writeBytes("exit\n");
            os.flush();
            process.waitFor();
        } catch (Exception e) {
            return false;
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                process.destroy();
            } catch (Exception e) {
            }
        }
        return true;
    }

    // 判断是否具有ROOT权限
    public static boolean is_root() {
        boolean res = false;
        try {
            if ((!new File("/system/bin/su").exists())
                    && (!new File("/system/xbin/su").exists())) {
                res = false;
            } else {
                res = true;
            }
        } catch (Exception e) {

        }
        return res;
    }

    public static String getErrorInfo(Throwable arg1) {
        Writer writer = new StringWriter();
        PrintWriter pw = new PrintWriter(writer);
        arg1.printStackTrace(pw);
        pw.close();
        String error = writer.toString();
        return error;
    }

    /**
     * 获取手机的硬件信息
     *
     * @return
     */
    public static String getMobileInfo() {
        StringBuffer sb = new StringBuffer();
        // 通过反射获取系统的硬件信息
        try {
            Field[] fields = Build.class.getDeclaredFields();
            for (Field field : fields) {
                // 暴力反射 ,获取私有的信息
                field.setAccessible(true);
                String name = field.getName();
                String value = field.get(null).toString();
                sb.append(name + "=" + value);
                sb.append("\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (TextUtils.isEmpty(sb)) {
            return "未知的手机信息";
        }
        return sb.toString();
    }

    /**
     * 获取手机的版本信息
     *
     * @return
     */
    public static String getVersionInfo(Context mContext) {
        try {
            PackageManager pm = mContext.getPackageManager();
            PackageInfo info = pm.getPackageInfo(mContext.getPackageName(), 0);
            return info.versionName;
        } catch (Exception e) {
            e.printStackTrace();
            return "版本号未知";
        }
    }

    /**
     * 获取当前应用程序的版本号。
     */
    public static int getAppVersionCode(Context context) {
        try {
            PackageInfo info = context.getPackageManager().getPackageInfo(
                    context.getPackageName(), 0);
            return info.versionCode;
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
        return 1;
    }

    /**
     * 判定输入法是否需要隐藏
     *
     * @param v
     * @param ev
     * @return
     */
    public static boolean isHideInput(View v, MotionEvent ev) {
        if (v != null && (v instanceof EditText)) {
            return !touchIsOnView(v, ev);
        }

        return false;

    }

    public static boolean touchIsOnView(View v, MotionEvent ev) {
        int[] l = getViewLocationOnView(v);
        int left = l[0], top = l[1], bottom = top + v.getHeight(), right = left
                + v.getWidth();
        if (ev.getX() > left && ev.getX() < right && ev.getY() > top
                && ev.getY() < bottom) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取view的屏幕上的坐标
     *
     * @param view
     * @return 整型数组，存放了view的左上角坐标（x,y）
     */
    public static int[] getViewLocationOnView(View view) {
        int[] l = {0, 0};
        view.getLocationInWindow(l);
        // view.getLocationOnScreen(location)
        return l;
    }

    //不支持用反射调用内部API
    @Deprecated
    public static int getStatusBarHeight(Context context) {

        Class<?> c = null;
        Object obj = null;
        Field field = null;
        int x = 0, sbar = 0;
        try {
            c = Class.forName("com.android.internal.R$dimen");
            obj = c.newInstance();
            field = c.getField("status_bar_height");
            x = Integer.parseInt(field.get(obj).toString());
            return sbar = context.getResources().getDimensionPixelSize(x);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return sbar;
    }

    public static String date2Str(Date date) {
        return QvTimeUtils.date2String(date, "yyyy-MM-dd HH:mm");
    }

    public static String date2Str(Date date, String format) {
        return QvTimeUtils.date2String(date, format);
    }

    /**
     * 字符串转换成日期
     *
     * @param str
     * @return date
     */
    public static Date strToDate(String str) {
        // 移除换行符
        str = removeLineFeed(str);
        return QvTimeUtils.string2Date(str, "yyyy-MM-dd HH:mm");
    }

    /**
     * @param str
     * @return
     */
    public static String removeLineFeed(String str) {
        String dest = "";
        if (!TextUtils.isEmpty(str)) {
            Pattern p = Pattern.compile("\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }

    /**
     * 字符串转换成日期
     *
     * @param str
     * @return date
     */
    public static Date strToDate(String str, String format) {
        return QvTimeUtils.string2Date(str, format);
    }

    /**
     * 保留两位小数
     *
     * @param f
     * @return
     */
    public static float save2Decimal(float f) {
        BigDecimal b = new BigDecimal(f);
        float f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
        return f1;
    }

    // public static String getImsi(Context context) {
    // String imsi;
    // TelephonyManager mTelephonyMgr = (TelephonyManager) context
    // .getSystemService(Context.TELEPHONY_SERVICE);
    // imsi = mTelephonyMgr.getSubscriberId();
    // if (imsi == null) {
    // imsi = mTelephonyMgr.getDeviceId();
    // if (imsi == null)
    // imsi = "000000000000";
    // }
    // return imsi;
    // }


    /**
     * 获取保存免登录下设备信息的路径
     */
    public static String getConfigPath(Context context) {
        // bug:13726 清除缓存，不会清除信息，清除数据可以清除
        return "//data//data//" + context.getPackageName() + "//" + "Config";
        // return context.getCacheDir().getPath();
    }

    /**
     * 设置滤镜效果
     *
     * @param contrast -1~1，-1 最暗到，1 最亮
     * @return
     */
    public static ColorMatrix setContrastScaleOnly(float contrast) {
        ColorMatrix cm = new ColorMatrix();
        float scale = contrast + 1.f;
        // float translate = (-.5f * scale + .5f) * 255.f;
        cm.set(new float[]{scale, 0, 0, 0, 0, 0, scale, 0, 0, 0, 0, 0, scale,
                0, 0, 0, 0, 0, 1, 0});
        return cm;
    }

    public static boolean hasApplication(Context context, Intent intent) {
        PackageManager packageManager = context.getPackageManager();
        // 查询是否有该Intent的Activity
        List<ResolveInfo> activities = packageManager.queryIntentActivities(
                intent, 0);
        // activities里面不为空就有，否则就没有
        return activities.size() > 0;
    }

    public static String getMimeType(String path) {
        // [bugFix]适配波斯语
        //String extension = MimeTypeMap.getFileExtensionFromUrl(path);
        String extension = getFileExtensionFromUrl(path);
        String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                extension);
        if (TextUtils.isEmpty(mimeType)) {
            return "*/*";
        }
        return mimeType;
    }

    /**
     * 重写 MimeTypeMap.getFileExtensionFromUrl(path) 方法，
     * -- 适配波斯语(不满足Pattern.matches)
     * <p>
     * Returns the file extension or an empty string iff there is no
     * extension. This method is a convenience method for obtaining the
     * extension of a url and has undefined results for other Strings.
     *
     * @param url
     * @return The file extension of the given url.
     */
    public static String getFileExtensionFromUrl(String url) {
        if (!TextUtils.isEmpty(url)) {
            int fragment = url.lastIndexOf('#');
            if (fragment > 0) {
                url = url.substring(0, fragment);
            }

            int query = url.lastIndexOf('?');
            if (query > 0) {
                url = url.substring(0, query);
            }

            int filenamePos = url.lastIndexOf('/');
            String filename =
                    0 <= filenamePos ? url.substring(filenamePos + 1) : url;

            // if the filename contains special characters, we don't
            // consider it valid for our matching purposes:
            if (!filename.isEmpty()
                /*  && Pattern.matches("[a-zA-Z_0-9\\.\\-\\(\\)\\%]+", filename) */) {
                int dotPos = filename.lastIndexOf('.');
                if (0 <= dotPos) {
                    return filename.substring(dotPos + 1);
                }
            }
        }

        return "";
    }

    public static boolean isEnglishOnly(String str) {
        int length = str.length();
        byte[] byt = str.getBytes();
        if (length == byt.length) {
            return true;
        }
        return false;
    }

    public static boolean isVideoFileUri(String uri) {
        String mimeType = getMimeType(uri);
        return mimeType != null && mimeType.startsWith("video/");
    }

    public static boolean isImageFileUri(String uri) {
        String mimeType = getMimeType(uri);
        return mimeType != null && mimeType.startsWith("image/");
    }

    public static boolean isVideoContentUri(Context context, Uri uri) {
        String mimeType = context.getContentResolver().getType(uri);
        return mimeType != null && mimeType.startsWith("video/");
    }

    /**
     * 读取照片exif信息中的旋转角度
     *
     * @param path 照片路径
     * @return角度 获取从相册中选中图片的角度
     */
    public static int readPictureDegree(String path) {
        if (TextUtils.isEmpty(path)) {
            return 0;
        }
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (Exception e) {
        }
        return degree;
    }

    /**
     * 获取视频缩略图 值得注意的是，此为耗时操作，需要在非ui线程中操作
     *
     * @param filePath
     * @return
     */
    public static Bitmap getVideoThumbnail(String filePath) {
        return ThumbnailUtils.createVideoThumbnail(filePath,
                Images.Thumbnails.MINI_KIND);
    }

    /**
     * 使用MD5算法对传入的key进行加密并返回。
     */
    public static String hashKeyForDisk(String key) {
        String cacheKey;
        try {
            final MessageDigest mDigest = MessageDigest.getInstance("MD5");
            mDigest.update(key.getBytes());
            cacheKey = bytesToHexString(mDigest.digest());
        } catch (NoSuchAlgorithmException e) {
            cacheKey = String.valueOf(key.hashCode());
        }
        return cacheKey;
    }

    private static String bytesToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(0xFF & bytes[i]);
            if (hex.length() == 1) {
                sb.append('0');
            }
            sb.append(hex);
        }
        return sb.toString();
    }

    /**
     * 添加图片显示渐现动画
     */
    public static void setImageBitmap(ImageView imageView, Bitmap bitmap,
                                      boolean isTran) {
        if (isTran) {
            final TransitionDrawable td = new TransitionDrawable(
                    new Drawable[]{
                            new ColorDrawable(App.getInstance().
                                    getResources().getColor(android.R.color.transparent)),
                            new BitmapDrawable(bitmap)});
            td.setCrossFadeEnabled(true);
            imageView.setImageDrawable(td);
            td.startTransition(300);
        } else {
            imageView.setImageBitmap(bitmap);
        }
    }

    /**
     * 判断手机屏幕是否竖屏
     *
     * @param context
     * @return true
     */
    public static boolean isPortait(Context context) {
        int orientation = context.getResources().getConfiguration().orientation;
        return orientation == Configuration.ORIENTATION_PORTRAIT;
    }

    /**
     * 获取屏幕宽高
     * 适配三星S8虚拟导航栏
     * todo u
     */
    public static Point getScreenSize(Activity activity) {

        WindowManager wm = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
        if (wm == null) return null;
        Display display = wm.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        /*
            适配三星s8，此时虚拟按钮显示，华为p9因监听无效，VIRTUAL_NAVIGATION_BAR_STATE 始终为 0
			该值始终不变，但对应getMetrics获取到的分辨率会自动发生改变
			对应三星s8获取getMetrics值始终不变
		 */
        if (PublicoVariate.VIRTUAL_NAVIGATION_BAR_STATE == 0 || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
            display.getMetrics(dm);
        } else {
            display.getRealMetrics(dm);
        }
        PublicoVariate.setScreenWidth(dm.widthPixels);
        PublicoVariate.setScreenHeight(dm.heightPixels);
        return new Point(dm.widthPixels, dm.heightPixels);
    }

    public static boolean isContains(Integer[] arr, int targetValue) {
        // int a = Arrays.binarySearch(arr, targetValue);
        // if (a > 0) {
        // return true;
        // } else {
        // return false;
        // }
        return Arrays.asList(arr).contains(targetValue);
    }

    /**
     * 检查string数组中是否有重复的元素
     *
     * @param items String数组
     * @return 是否有重复元素
     */
    public static boolean checkStringRepeat(String[] items) {
        if (items == null || items.length <= 1) {
            return false;
        }

        Set<String> set = new HashSet<>();
        for (String value : items) {
            if (set.contains(value)) {
                return true;
            }
            set.add(value);
        }

        return false;
    }

    @ColorInt
    public static int getTitleColor(@ColorInt int bgColor) {
        if (QvSystemUtil.isLightColor(bgColor)) {
            return Color.parseColor("#333333");
        } else {
            return Color.WHITE;
        }
    }

}
